package com.openlogic.logic.controller.logic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.constraints.NotNull;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.noear.solon.annotation.Body;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Delete;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.annotation.Path;
import org.noear.solon.annotation.Post;
import org.noear.solon.annotation.Put;
import org.noear.solon.auth.annotation.AuthPermissions;
import org.noear.solon.core.handle.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.paginate.Page;
import com.openlogic.api.logic.entity.RuleModelDeploy;
import com.openlogic.common.core.enums.BusinessType;
import com.openlogic.common.core.exception.logic.RuleException;
import com.openlogic.common.core.web.controller.BaseController;
import com.openlogic.common.core.web.domain.PageData;
import com.openlogic.common.datasource.annotation.QzLog;
import com.openlogic.common.logic.annotation.RuleLog;
import com.openlogic.common.logic.constants.RuleTypeConstants;
import com.openlogic.common.logic.node.enums.NodeExecEnums;
import com.openlogic.common.logic.node.enums.ParseTypeEnums;
import com.openlogic.common.logic.node.factory.NodeExecFactory;
import com.openlogic.common.logic.node.factory.NodeParseFactory;
import com.openlogic.common.logic.node.parse.BaseParseHandler;
import com.openlogic.common.logic.run.ExecRuleHandler;
import com.openlogic.logic.service.logic.RuleModelDeployService;
import com.openlogic.logic.service.logic.RuleModelNodeMergeService;
import com.openlogic.logic.service.logic.RuleModelService;

/**
* @ClassName: RuleModelDeployController
* @Description: 规则模型Controller
* @author weiyongpeng
* @date 2024年7月14日 上午10:42:13
 */
@Controller
@Mapping("rule/model/deploy")
public class RuleModelDeployController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(RuleModelDeployController.class);
	
	@Inject
	private RuleModelDeployService ruleModelDeployService;
	
	@Inject
	private RuleModelService ruleModelService;
	
	@Inject
	private RuleModelNodeMergeService ruleModelNodeMergeService;
	
	/**
	* 描述：根据条件查询符合条件的规则模型
	* @Title: listRuleModeDeployes
	* @param ruleModelDeploy
	* @return
	* @author weiyongpeng
	* @date  2024年7月14日 上午10:42:08
	 */
	@Get
	@Mapping("listRuleModelDeployes")
	@AuthPermissions("rule:model:deploy:list")
	@QzLog(title = "规则模型查询", businessType = BusinessType.LIST)
	public PageData<RuleModelDeploy> listRuleModeDeployes(Page<RuleModelDeploy> page, @Param(required = false) RuleModelDeploy ruleModelDeploy) {
		startPage(page);
		return getPageData(this.ruleModelDeployService.findRuleDeployList(ruleModelDeploy));
	}
	
	/**
	* 描述：根据规则key查询规则列表
	* @Title: listRuleModeDeployes
	* @param ruleModelDeploy
	* @return
	* @author weiyongpeng
	* @date  2024年7月18日 上午11:28:08
	 */
	@Get
	@Mapping("listRuleModelByParams")
	@AuthPermissions("rule:model:deploy:list")
	@QzLog(title = "根据规则key查询规则列表", businessType = BusinessType.LIST)
	public PageData<RuleModelDeploy> listRuleModelByParams(Page<RuleModelDeploy> page, @Param Map<String, Object> params) {
		startPage(page);
		List<RuleModelDeploy> list = this.ruleModelDeployService.findRuleDeployByParams(params);
		return getPageData(list);
	}
	
	/**
	* 描述：根据规则Id查询规则
	* @Title: listRuleModeDeployes
	* @param ruleModelDeploy
	* @return
	* @author weiyongpeng
	* @date  2024年7月18日 上午11:28:08
	 */
	@Get
	@Mapping("listRuleModelById")
	@AuthPermissions("rule:model:deploy:list")
	@QzLog(title = "根据规则Id查询规则", businessType = BusinessType.LIST)
	public PageData<RuleModelDeploy> listRuleModelById(@Param Map<String, Object> params) {
		if(params.get("ruleModelId") == null && params.get("ruleModelId").toString().equals("")) {
			throw new RuleException("规则id不能为空");
		}
		List<RuleModelDeploy> list = this.ruleModelDeployService.findRuleDeployByParams(params);
		if(list.size() > 0) {
			return getPageData(list);
		}
		return getPageData(new ArrayList<>());
	}
	
	/**
	* 描述：保存规则模型
	* @Title: save
	* @param ruleModelVersion
	* @param ruleModelName
	* @param ruleRawValue
	* @param ruleModelValue
	* @param id
	* @param remark
	* @return
	* @author weiyongpeng
	* @date  2024年8月3日 下午7:16:26
	 */
	@Post
	@Mapping(value = "save")
	@AuthPermissions("rule:model:deploy:add")
	@QzLog(title = "规则模型保存", businessType = BusinessType.INSERT)
	public Result<String> save(
			@Param(value="ruleModelVersion",required = false) String ruleModelVersion,
			@Param(value="ruleModelName",required = false) String ruleModelName,
			@Param(value="ruleRawValue",required = false) String ruleRawValue,
			@Param(value="ruleModelValue",required = false) String ruleModelValue,
			@Param(value="id",required = false) String id,
			@Param(value="remark",required = false) String remark
	 ) {
		try {
			RuleModelDeploy ruleModelDeploy = new RuleModelDeploy();
			if(id != null && StringUtils.isNotBlank(id)) {
				ruleModelDeploy.setId(id);
			}if(ruleModelVersion != null && StringUtils.isNotBlank(ruleModelVersion)) {
				ruleModelDeploy.setRuleModelVersion(ruleModelVersion);
			}if(ruleModelName != null && StringUtils.isNotBlank(ruleModelName)) {
				ruleModelDeploy.setRuleModelName(ruleModelName);
			}if(ruleRawValue != null && StringUtils.isNotBlank(ruleRawValue)) {
				ruleModelDeploy.setRuleRawValue(ruleRawValue);
			}if(ruleModelValue != null && StringUtils.isNotBlank(ruleModelValue)) {
				ruleModelDeploy.setRuleModelValue(ruleModelValue);
			}if(remark != null && StringUtils.isNotBlank(remark)) {
				ruleModelDeploy.setRemark(remark);
			}
			String resValue = "";
			if (ruleModelDeploy.getRuleModelValue() != null) {
				BaseParseHandler baseParseHandler = NodeParseFactory.getInvokeStrategyMap(ParseTypeEnums.DEFAULT_INFO.getParsetype());
				ruleModelValue = StringEscapeUtils.unescapeXml(ruleModelDeploy.getRuleModelValue());
				ruleModelDeploy.setRuleModelValue(ruleModelValue);
				resValue = baseParseHandler.getResValue(ruleModelValue);
				resValue = StringEscapeUtils.unescapeXml(resValue);
				logger.info("resValue={}", JSON.parseObject(resValue).toString());
			}
			// 保存规则信息
			ruleModelDeployService.save(ruleModelDeploy, resValue);
			return Result.succeed();
		} catch (Exception e) {
			logger.error("添加错误：{}", e);
			return Result.failure("添加错误，请联系开发人员检查");
		}
	}
	
	/**
	* 描述：修改规则状态
	* @Title: updateStatus
	* @param ruleModelDeploy
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 上午11:24:49
	 */
	@Put
	@Mapping("updateStatus")
	@AuthPermissions("rule:model:deploy:update")
	@QzLog(title = "规则模型状态修改", businessType = BusinessType.UPDATE)
	public Result<String> updateStatus(@Body RuleModelDeploy ruleModelDeploy) {
		boolean updateFlag = ruleModelDeployService.updateStatus(ruleModelDeploy);
		if (updateFlag) {
			return Result.succeed("规则状态修改成功");
		}
		return Result.failure("规则修改,暂无修改数据");
	}
	
	/**
	* 描述：删除规则
	* @Title: delete
	* @param id
	* @return
	* @author weiyongpeng
	* @date  2024年7月16日 上午11:24:49
	 */
	@Delete
	@Mapping("delete/{id}")
	@AuthPermissions("rule:model:deploy:delete")
	@QzLog(title = "规则模型状态删除", businessType = BusinessType.DELETE)
	public Result<String> delete(@Path("id") String id) {
		boolean deleteFlag = ruleModelDeployService.delete(id);
		if (deleteFlag) {
			ruleModelService.deleteByRuleKey(id);
			ruleModelNodeMergeService.deleteByRuleKey(id);
			return Result.succeed("规则状态删除成功");
		}
		return Result.failure("规则删除,暂无删除数据");
		
	}
	
	/**
	* 描述：规则模型调试
	* @Title: debug
	* @param dataInfo 入参
	* @param jsonStr  规则图里数据
	* @param ruleAttr 规则属性
	* @return
	* @author weiyongpeng
	* @date  2024年7月28日 下午4:21:05
	 */
	@Post
	@Mapping(value = "debug")
	@AuthPermissions("rule:model:deploy:list")
	@RuleLog(ruleType = RuleTypeConstants.ruleflow)
	public Result<String> debug(@Param("datas") String dataInfo,
							@Param("jsonStr") String jsonStr,
							@Param("ruleAttr") String ruleAttr,
							@Param(value="ruleId") String ruleId,
							@Param(value="ruleRawValue") String ruleRawvalue) {
		try {
			jsonStr = StringEscapeUtils.unescapeXml(jsonStr);
			JSONArray ruleAttrArray = JSON.parseArray(ruleAttr);
			// 第一次解析
			BaseParseHandler baseParseHandler = NodeParseFactory.getInvokeStrategyMap(ParseTypeEnums.DEFAULT_INFO.getParsetype());
			String resValue = baseParseHandler.getResValue(jsonStr);
			JSONObject resJson = JSON.parseObject(resValue);
			resJson.put("ruleId","");
			resValue = resJson.toString();
			// 将规则变量拆分成Map结构
			Map<String,Object> ruleAttrMap = new HashMap<>();
			for (Object object : ruleAttrArray) {
				JSONObject jsonObject = JSONObject.parseObject(object.toString());
				// key:modelIdentify value:name
				ruleAttrMap.put(jsonObject.getString("modelIdentify"), jsonObject.getString("name"));
			}
			StringBuffer reason = new StringBuffer();
			logger.info("resValue={}", resValue);
			logger.info("dataInfo={}", dataInfo);
			logger.info("ruleAttrMap={}", ruleAttrMap.toString());
			// 执行
			ExecRuleHandler execRuleHandler = NodeExecFactory.getInvokeStrategyMap(NodeExecEnums.DEFAULT_NODE.getCode());
			String resultJson = execRuleHandler.runAndGetResult(resValue, dataInfo, reason, ruleAttrMap);
			logger.info("resultJsonBefore={}",resultJson);
			logger.info("reason={}", reason);
			// 调整resultJson结构
			if (resultJson != null && StringUtils.isNotBlank(resultJson)) {
				resultJson = execRuleHandler.changeEveryNodeList(resultJson, reason);
			}
			logger.info("resultJsonAfter={}",resultJson);
			return Result.succeed(resultJson);
		} catch (Exception e) {
			logger.error("执行错误：{}", e);
			throw new RuleException("执行错误");
		}
	}
	
	/**
	* 描述：校验规则公式合法性 
	* @Title: checkFormulae
	* @param params
	* @return
	* @throws Exception 
	* @author weiyongpeng
	* @date  2024年7月26日 上午9:54:45
	 */
	@Post
	@Mapping("checkFormulae")
	@AuthPermissions("rule:model:deploy:list")
	@QzLog(title = "校验规则公式合法性", businessType = BusinessType.OTHER)
	public Result<List<Map<String, Object>>> checkFormulae(@Body Map<String, Object> params) throws Exception {
		// 执行规则
		List<Map<String, Object>> resultJson = ruleModelDeployService.checkFormulae(params);
		return Result.succeed(resultJson);
	}
	
	@Get
	@Mapping("execuate")
	@QzLog(title = "规则模型调试", businessType = BusinessType.OTHER)
	public Result<String> execuate(@Param("datas") String datas, @Param("id") @NotNull String id, @Param("operateNo") String operateNo) {
		// 执行规则
		String resultJson = ruleModelDeployService.execuateRule(datas,id,operateNo);
		Map<String, Object> parseMap = (Map<String, Object>)JSONObject.parseObject(resultJson);
		Map<String, Object> dataMap = (Map<String, Object>)JSONObject.parseObject(datas);
		
		parseMap.entrySet().removeIf(entry -> dataMap.containsKey(entry.getKey()));
		Map<String,Object> resultMap = new HashMap<>();
		String caclKey = "caclRes";
		parseMap.entrySet().forEach(entry -> {
			resultMap.put(caclKey, entry.getValue());
		});
		return Result.succeed(new JSONObject(resultMap).toString());
	}
	
	@Get
	@Mapping("listRuleModelInner")
	@AuthPermissions("rule:model:deploy:list")
	@QzLog(title = "查询规则列表-内部调用", businessType = BusinessType.LIST)
	public PageData<RuleModelDeploy> listRuleModelInner(@Param Map<String, Object> params) {
		List<RuleModelDeploy> list = this.ruleModelDeployService.findRuleDeployModel(params);
		return getPageData(list);
	}
}
